// START EVENT COMBINATIONS

import { resultSuccess } from '@utils/resultFormatter'
import { resultFailure } from '@utils/resultFormatter'
import { checkEventExists } from '@repos/event/event.repo'
import { prisma } from '@repos/index.repo'

export const createEventCombination = async (orgId: string, name: string, description: string, eventIds?: string[]) => {
    try {
        const result = await prisma.eventCombination.create({
            data: {
                organizationId: orgId,
                name,
                description,
                Events: {
                    connect: eventIds?.map(id => ({ id })) || []
                }
            }
        })

        if (!result) return resultFailure(false, 500, 'Failed to create event combination')

        return resultSuccess(true, 201, result, 'Event combination created successfully')
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

export const deleteEventCombination = async (ecId: string) => {
    try {
        const result = await prisma.$transaction(async tx => {
            await tx.eventCombinationGroup.updateMany({
                where: { eventCombinationId: ecId },
                data: { deletedAt: new Date() }
            })
            await tx.eventCombination.updateMany({
                where: { id: ecId },
                data: { deletedAt: new Date() }
            })
            return true
        })

        if (!result) return resultFailure(false, 404, 'Event combination not found')

        return resultSuccess(true, 200, result, 'Event combination deleted successfully')
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

export const updateEventCombination = async (ecId: string, name: string, description: string) => {
    try {
        const result = await prisma.eventCombination.update({
            where: { id: ecId },
            data: { name, description }
        })

        if (!result) return resultFailure(false, 404, 'Event combination not found')

        return resultSuccess(true, 200, result, 'Event combination updated successfully')
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

export const updateEventCombinationEvents = async (ecId: string, eventIds: string[]) => {
    if (!eventIds || eventIds.length === 0) {
        return resultFailure(false, 400, 'Event IDs array cannot be empty')
    }

    try {
        const validationResults = await Promise.all(
            eventIds.map(async id => {
                const exists = await checkEventExists(id)
                return { id, exists: exists.status }
            })
        )

        const invalidIds = validationResults.filter(r => !r.exists)
        if (invalidIds.length > 0) {
            return resultFailure(false, 400, `Invalid event IDs: ${invalidIds.map(r => r.id).join(', ')}`)
        }

        const result = await prisma.eventCombination.update({
            where: { id: ecId },
            data: {
                Events: {
                    set: eventIds.map(id => ({ id }))
                }
            }
        })

        return resultSuccess(true, 200, result, 'Event combination events updated successfully')
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

export const readEventCombinationList = async (
    orgId: string | undefined = undefined,
    offset: number = 0,
    limit: number = 10
) => {
    try {
        const result = await prisma.eventCombination.findMany({
            where: { organizationId: orgId, deletedAt: null },
            skip: offset,
            take: limit
        })

        if (result.length === 0) return resultFailure(false, 404, 'No event combinations found')

        return resultSuccess(true, 200, result, 'Event combination list retrieved successfully')
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

// 获取事件组详细，包括关联的事件和用户组
export const readEventCombination = async (ecId: string) => {
    try {
        const result = await prisma.eventCombination.findUnique({
            where: { id: ecId },
            include: {
                Events: {
                    select: {
                        id: true,
                        title: true,
                        description: true,
                        startAt: true,
                        endAt: true
                    }
                },
                EventCombinationGroup: {
                    select: {
                        group: {
                            select: {
                                id: true,
                                name: true
                            }
                        }
                    }
                }
            }
        })

        if (!result) return resultFailure(false, 404, 'Event combination not found')

        return resultSuccess(true, 200, result, 'Event combination retrieved successfully')
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

export const readEventCombinationByGroup = async (gId: string) => {
    try {
        const result = await prisma.eventCombination.findMany({
            where: {
                EventCombinationGroup: {
                    some: {
                        groupId: gId
                    }
                }
            }
        })

        if (!result) return resultFailure(false, 404, 'Event combinations not found for the group')

        return resultSuccess(true, 200, result, 'Event combinations retrieved successfully')
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

export const readEventCombinationEventList = async (ecId: string) => {
    try {
        const result = await prisma.eventCombination.findUnique({
            where: { id: ecId },
            include: {
                Events: {
                    select: {
                        id: true,
                        title: true,
                        description: true,
                        startAt: true,
                        endAt: true,
                        EventSetting: true
                    }
                }
            }
        })

        if (!result) return resultFailure(false, 404, 'Event combination not found')

        return resultSuccess(true, 200, result, 'Event combination retrieved successfully')
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

export const readEventCombinationEventListByArray = async (ecId: string[]) => {
    try {
        const result = await prisma.eventCombination.findMany({
            where: { id: { in: ecId } },
            include: {
                Events: {
                    select: {
                        id: true,
                        title: true,
                        description: true,
                        startAt: true,
                        endAt: true,
                        EventSetting: true
                    }
                }
            }
        })

        if (!result) return resultFailure(false, 404, 'Event combination not found')

        return resultSuccess(true, 200, result, 'Event combination retrieved successfully')
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

export const readEventCombinationEventListByGroup = async (gId: string) => {
    try {
        const getEcId = await readEventCombinationByGroup(gId)

        if (!getEcId.status || !getEcId.data)
            return resultFailure(false, 404, 'Event combinations not found for the group')

        const ecIds = getEcId.data.map(i => i.id)

        const result = await (await readEventCombinationEventListByArray(ecIds)).data

        if (!result) return resultFailure(false, 404, 'Event combination events not found')

        if (result.length < 1) return resultFailure(false, 404, 'No events found for the group')

        return resultSuccess(true, 200, result, 'Event combination events retrieved successfully')
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}
